#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "Bone.h"
#include "Ransac.h"

using namespace std;

/*
vector<cv::Point> FindBigestContour(cv::Mat src_img)
{
    int imax = 0;
    int imaxcontour = -1;
    std::vector<std::vector<cv::Point>>contours;
    cv::findContours(src_img, contours, cv::RETR_LIST, cv::CHAIN_APPROX_NONE);
    for (int i = 0; i < contours.size(); i++)
    {
        int itmp = contourArea(contours[i]);
        if (imaxcontour < itmp)
        {
            imax = i;
            imaxcontour = itmp;
        }
    }
    return contours[imax];
}
*/

cv::Mat moveLightDiff(cv::Mat src_img, int radius)
{
    cv::Mat dst;
    cv::Mat src_clone = src_img.clone();
    cv::Mat mask = cv::Mat::zeros(radius * 2, radius * 2, CV_8U);
    circle(mask, cv::Point(radius, radius), radius, cv::Scalar(255), -1);
    //top hat
    erode(src_clone, src_clone, mask);
    dilate(src_clone, src_clone, mask);
    dst = src_img - src_clone;
    return dst;
}

int main()
{
    clock_t startTime,endTime;
    cv::VideoCapture capture("/home/ubu/桌面/2019RC/2019RCcode/process2/01.avi");
    if (!capture.isOpened())
    {
        cerr << "Fail to open" << endl;
    }
    while(1)
    {
        startTime = clock();
        cv::Mat src_img;
        bool bSuccess = capture.read(src_img);
        if (!bSuccess)
        {
            cout << "Cannot read a frame from video stream" << endl;
            break;
        }
        cv::Mat gray_img, src_mask;
        //src_img = cv::imread("/home/ubu/桌面/2019RC/2019RCcode/process2/nomovepicture/138.png");

        Mat mask = cv::Mat::zeros(src_img.size(), CV_8UC1);
        Point rook_Points[1][4];
        rook_Points[0][0] = Point(300, 360);
        rook_Points[0][1] = Point(980, 360);
        rook_Points[0][2] = Point(1080, 720);
        rook_Points[0][3] = Point(300, 720);
        const Point *ppt[1] = {rook_Points[0]};
        int npt[] = {4};
        cv::fillPoly(mask, ppt, npt, 1, cv::Scalar(255, 255, 255), 0);
        //imshow("mask", mask);

        src_img.copyTo(src_mask, mask);
        //cv::imshow("srcmask", src_mask);

        /*
        单一hsv颜色提取
        */
/*    cv::Mat tmpHSV_img, white_img, HSV_img, bin_img;
    vector<cv::Mat> hsvSplit;
    src_mask.copyTo(tmpHSV_img);
    cv::cvtColor(tmpHSV_img, HSV_img, cv::COLOR_BGR2HSV);
    cv::inRange(HSV_img, cv::Scalar(0, 0, 190), cv::Scalar(180, 43, 255), bin_img);
    cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(1, 1));
    cv::morphologyEx(bin_img, bin_img, cv::MORPH_OPEN, element);
    cv::morphologyEx(bin_img, bin_img, cv::MORPH_CLOSE, element);
    cv::dilate(bin_img, bin_img, cv::Mat(), cv::Point(-1, -1), 1);
    cv::erode(bin_img, bin_img, cv::Mat(), cv::Point(-1, -1), 1);*/

        cv::Mat tmpRGB_img;
        src_mask.copyTo(tmpRGB_img);
        for (int i = 350; i < tmpRGB_img.rows; i++) {
            for (int j = 290; j < tmpRGB_img.cols; j++) {
                if (tmpRGB_img.at<cv::Vec3b>(i, j)[0] < 177 && tmpRGB_img.at<cv::Vec3b>(i, j)[1] < 200 &&
                    tmpRGB_img.at<cv::Vec3b>(i, j)[2] > 0) {
                    tmpRGB_img.at<cv::Vec3b>(i, j)[0] = 0;
                    tmpRGB_img.at<cv::Vec3b>(i, j)[1] = 0;
                    tmpRGB_img.at<cv::Vec3b>(i, j)[2] = 0;
                }
            }
        }
        cv::imshow("RGB", tmpRGB_img);

        cv::Mat tmpHSV_img, white_img, HSV_img, bin_img, H_img;
        tmpRGB_img.copyTo(tmpHSV_img);
        //src_mask.copyTo(tmpHSV_img);
        cv::cvtColor(tmpHSV_img, HSV_img, cv::COLOR_BGR2HSV);
        vector<cv::Mat> rgb_planes;
        split(HSV_img, rgb_planes);
        //H_img = rgb_planes[1] + rgb_planes[0]; // v channel is useful
        H_img = rgb_planes[1];
        //H_img = rgb_planes[2];
        H_img = moveLightDiff(H_img, 20);

        //cv::imshow("H", H_img);
        cv::threshold(H_img, bin_img, 100, 255, cv::THRESH_OTSU);
        cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(1, 1));
        cv::morphologyEx(bin_img, bin_img, cv::MORPH_OPEN, element);
        cv::morphologyEx(bin_img, bin_img, cv::MORPH_CLOSE, element);

        cv::Mat bin_mask;
        Mat mask2 = cv::Mat::zeros(src_img.size(), CV_8UC1);
        Point rook_Points2[1][4];
        rook_Points2[0][0] = Point(310, 370);
        rook_Points2[0][1] = Point(1000, 370);
        rook_Points2[0][2] = Point(1000, 720);
        rook_Points2[0][3] = Point(310, 720);
        const Point *ppt2[1] = {rook_Points2[0]};
        int npt2[] = {4};
        cv::fillPoly(mask2, ppt2, npt2, 1, cv::Scalar(255, 255, 255), 0);
        //imshow("mask", mask);

        bin_img.copyTo(bin_mask, mask2);
        cv::imshow("binmask", bin_mask);

        /*vector<cv::Point> bigestcontour = FindBigestContour(bin_img);
        vector<vector<cv::Point>> contours;
        contours.push_back(bigestcontour);
        cv::drawContours(src_img, contours, 0, cv::Scalar(0, 0, 255), 3);
        cv::drawContours(bin_img, contours, 0, cv::Scalar(0, 0, 255), 3);*/

/*        vector<vector<cv::Point>> contours;
        cv::findContours(bin_mask, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
        vector<cv::Rect> rect(contours.size());
        for (int i = 0; i < contours.size(); i++)
        {
            rect[i] = cv::boundingRect(contours[i]);
            double x = rect[i].x;
            double y = rect[i].y;
            double width = rect[i].width;
            double height = rect[i].height;
            if (!(width * height > 90000 || width * height < 200)) {
                cv::rectangle(src_img, cv::Point(x, y), cv::Point(x + width, y + height), cv::Scalar(0, 255, 0), 2);
            }
        }*/

        endTime = clock();
        cout << "Totle Time : " <<(double)(endTime - startTime) / CLOCKS_PER_SEC << "s" << endl;

        cv::imshow("original", src_img);
        //cv::imshow("bin", bin_img);
        cv::waitKey(1);
    }
    return 0;
}